package com.database.objects;

import static com.load.utils.DeveloperUtil.getProcessedName;

import java.io.*;
import java.util.*;

import javax.persistence.*;

import com.google.common.collect.*;
import com.metrics.objects.*;

@Entity
@Table(name = "project")
public class Project implements Serializable {

	private static final long serialVersionUID = -4136438828166905089L;

	public static final List<String> REPOSITORIES = Lists.newArrayList("VERSION REPOSITORY", "TRACKER REPOSITORY");

	@Id
	@Column(name = "pro_name", nullable = false, unique = true)
	private String name;

	@org.hibernate.annotations.Type(type = "text")
	@Column(name = "pro_description", nullable = false)
	private String description;

	@Embedded
	private VersionRepository versionRepository = new VersionRepository();

	@Embedded
	private TrackerRepository trackerRepository = new TrackerRepository();

	@Embedded
	private Data data = new Data();

	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "project")
	@OrderBy("name")
	private List<Developer> developers = new ArrayList<Developer>();

	public Project() {

	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		description = description != null ? description : "";
		this.description = description;
	}

	public VersionRepository getVersionRepository() {
		return versionRepository;
	}

	public void setVersionRepository(VersionRepository versionRepository) {
		this.versionRepository = versionRepository;
	}

	public TrackerRepository getTrackerRepository() {
		return trackerRepository;
	}

	public void setTrackerRepository(TrackerRepository trackerRepository) {
		this.trackerRepository = trackerRepository;
	}

	public Data getData() {
		return data;
	}

	public void setData(Data data) {
		this.data = data;
	}

	public List<Developer> getDevelopers() {
		return developers;
	}

	public int getNumberDevelopers() {
		return developers.size();
	}

	public void addDeveloper(Developer developer) {
		Developer oldDeveloper = getDeveloperByName(developer.getName());
		if (oldDeveloper == null) {
			developers.add(developer);
		}
	}

	public Developer getDeveloperByName(String name) {
		name = name != null ? getProcessedName(name) : "";
		for (Developer developer : developers) {
			if (developer.getName().equals(name)) {
				return developer;
			}
		}
		return null;
	}

	public String getShortDescription() {
		int size = description.length() > 80 ? 80 : description.length();
		return description.substring(0, size) + " ...";
	}

	public void clone(Project other) {
		trackerRepository = other.getTrackerRepository();
		versionRepository = other.getVersionRepository();
		data = other.getData();
		developers = other.getDevelopers();
	}

	public Repository getRepository(String repository) {
		if (repository.equals(REPOSITORIES.get(0))) {
			return versionRepository;
		} else if (repository.equals(REPOSITORIES.get(1))) {
			return trackerRepository;
		}
		return null;
	}

	public static List<Type> getTypes(String repository) {
		if (repository.equals(REPOSITORIES.get(0))) {
			return VersionRepository.TYPES;
		} else if (repository.equals(REPOSITORIES.get(1))) {
			return TrackerRepository.TYPES;
		}
		return new ArrayList<Type>();
	}

	public static List<Status> getStatus(String repository) {
		if (repository.equals(REPOSITORIES.get(0))) {
			return VersionRepository.STATUS;
		} else if (repository.equals(REPOSITORIES.get(1))) {
			return TrackerRepository.STATUS;
		}
		return new ArrayList<Status>();
	}

	public static List<Metric> getMetrics(String repository) {
		if (repository.equals(REPOSITORIES.get(0))) {
			return VersionRepository.METRICS;
		} else if (repository.equals(REPOSITORIES.get(1))) {
			return TrackerRepository.METRICS;
		}
		return new ArrayList<Metric>();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (name == null ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		Project other = (Project) obj;
		if (name == null) {
			if (other.name != null) {
				return false;
			}
		} else if (!name.equals(other.name)) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		return "" + name;
	}

}